home *** CD-ROM | disk | FTP | other *** search
- /*
- ** termLocale.c
- **
- ** Localization support routines
- **
- ** Copyright © 1990-1995 by Olaf `Olsen' Barthel
- ** All Rights Reserved
- */
-
- #include "termGlobal.h"
-
- /* The catalog data is stored in the following format. */
-
- struct CatCompArrayType
- {
- LONG cca_ID;
- STRPTR cca_Str;
- };
-
- extern struct CatCompArrayType *AppStrings;
- extern LONG NumAppStrings;
-
- /* LocaleOpen(STRPTR CatalogName,STRPTR BuiltIn):
- *
- * Open string translation tables.
- */
-
- VOID __regargs
- LocaleOpen(STRPTR CatalogName,STRPTR BuiltIn,LONG Version)
- {
- if(LocaleBase = (struct LocaleBase *)OpenLibrary("locale.library",38))
- {
- if(LocaleBase -> lb_SysPatches)
- {
- strcpy(ConvNumber,"%lD");
- strcpy(ConvNumber10,"%10lD");
-
- if(Catalog = OpenCatalog(NULL,CatalogName,
- OC_BuiltInLanguage, BuiltIn,
- OC_BuiltInCodeSet, 0,
-
- Language[0] ? OC_Language : TAG_IGNORE,Language,
- TAG_DONE))
- {
- BOOL TooOld = FALSE;
-
- // Don't load an outdated catalog file
-
- if(Catalog -> cat_Version < Version)
- TooOld = TRUE;
- else
- {
- if(strcmp(GetCatalogStr(Catalog,MSG_OFFSET_TEST1_TXT,""),"v4.0"))
- TooOld = TRUE;
- }
-
- if(TooOld)
- {
- if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
- {
- MyEasyRequest(NULL,"The catalog file is too old to be used\nwith this `term' revision.","Continue");
-
- CloseLibrary(IntuitionBase);
-
- IntuitionBase = NULL;
- }
-
- CloseCatalog(Catalog);
-
- Catalog = NULL;
- }
- }
-
- Locale = OpenLocale(NULL);
- }
- else
- {
- if(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0))
- {
- MyEasyRequest(NULL,"Your \"locale.library\" is not installed correctly.","Continue");
-
- CloseLibrary(IntuitionBase);
-
- IntuitionBase = NULL;
- }
-
- strcpy(ConvNumber,"%ld");
- strcpy(ConvNumber10,"%10ld");
-
- CloseLibrary(LocaleBase);
-
- LocaleBase = NULL;
- }
- }
- else
- {
- strcpy(ConvNumber,"%ld");
- strcpy(ConvNumber10,"%10ld");
- }
- }
-
- /* LocaleClose():
- *
- * Close the translation tables.
- */
-
- VOID
- LocaleClose()
- {
- if(Locale)
- {
- CloseLocale(Locale);
-
- Locale = NULL;
- }
-
- if(Catalog)
- {
- CloseCatalog(Catalog);
-
- Catalog = NULL;
- }
-
- if(LocaleBase)
- {
- CloseLibrary(LocaleBase);
-
- LocaleBase = NULL;
- }
- }
-
- /* LanguageCheck():
- *
- * Checks to see if the currently selected language
- * is english.
- */
-
- VOID
- LanguageCheck()
- {
- if(Locale && Catalog)
- {
- if(Locale -> loc_LanguageName)
- {
- if(!Stricmp(Locale -> loc_LanguageName,"english.language"))
- English = TRUE;
- else
- English = FALSE;
- }
- else
- English = FALSE;
- }
- else
- English = TRUE;
- }
-
- /* LocaleSeconds(WORD Seconds):
- *
- * Return seconds in proper format.
- */
-
- STRPTR __regargs
- LocaleSeconds(WORD Seconds)
- {
- STATIC UBYTE Time[10];
-
- if(Locale)
- SPrintf(Time,"%2lD%s%02lD",Seconds / 100,Locale -> loc_DecimalPoint,Seconds % 100);
- else
- SPrintf(Time,"%2ld.%02ld",Seconds / 100,Seconds % 100);
-
- return(Time);
- }
-
- /* SmallCurrency():
- *
- * Support function for the rates control panel, returns a formatted
- * string to contain a string like "cents/unit".
- */
-
- STRPTR
- SmallCurrency()
- {
- STATIC UBYTE Buffer[30];
-
- if(Locale)
- SPrintf(Buffer,LocaleString(MSG_RATEPANEL_PAY_PER_UNIT_GAD),Locale -> loc_MonSmallCS);
- else
- SPrintf(Buffer,LocaleString(MSG_RATEPANEL_PAY_PER_UNIT_GAD),"Pay");
-
- return(Buffer);
- }
-
- /* InsertGrouping(STRPTR Buffer,STRPTR GroupData,STRPTR GroupSeparator):
- *
- * Tricky stuff, folks! This beauty will insert grouping characters
- * into a readily-prepared string buffer filled with numeric
- * contents. It takes the group separator tokens and group separator
- * strings into account.
- */
-
- VOID __regargs
- InsertGrouping(STRPTR Buffer,STRPTR GroupData,STRPTR GroupSeparator)
- {
- UBYTE LocalBuffer[80]; // Sufficient, but too large
- STRPTR Index;
- LONG i,j,SeparatorSize;
- WORD Count; // How many characters per group
- BOOL RepeatGroupCount; // Keep repeating group size until end
-
- // Set up for the first group
-
- switch(*GroupData)
- {
- case 0: // Repeat current grouping scheme until end
- case 255: // No further grouping is to be performed
-
- Count = 0;
-
- break;
-
- default: // Initial group size
-
- RepeatGroupCount = FALSE;
-
- Count = *GroupData++;
-
- break;
- }
-
- // Check the size of the group separator string
-
- if((SeparatorSize = strlen(GroupSeparator) - 1) < 1)
- Count = 0;
-
- // That where we'll start
-
- Index = LocalBuffer;
-
- // Build the string back to front, we will reverse it later
-
- for(i = strlen(Buffer) - 1, j = 1 ; i >= 0 ; i--, j++)
- {
- // Pick up the next number character
-
- *Index++ = Buffer[i];
-
- // Are we to insert the grouping characters here?
-
- if(Count && j == Count)
- {
- LONG k;
-
- // Insert the grouping characters
-
- for(k = SeparatorSize ; k >= 0 ; k--)
- *Index++ = GroupSeparator[k];
-
- // Reset the group size counter
-
- j = 0;
-
- // Pick up the next grouping token?
-
- if(!RepeatGroupCount)
- {
- // Ok, what kind of token is it?
-
- switch(*GroupData)
- {
- case 0: // Repeat current grouping scheme
-
- RepeatGroupCount = TRUE;
- break;
-
- case 255: // Perform no further grouping
-
- Count = 0;
- break;
-
- default: // New group size
-
- Count = *GroupData++;
- break;
- }
- }
- }
- }
-
- // Look how long the resulting string is
-
- j = (LONG)((ULONG)Index - (ULONG)LocalBuffer) - 1;
-
- // Copy it back
-
- Index = Buffer;
-
- // Reverse the order of characters while copying
-
- for(i = j ; i >= 0 ; i--)
- *Index++ = LocalBuffer[i];
-
- // Provide null-termination
-
- *Index = 0;
- }
-
- VOID __regargs
- ConvertMonetaryQuantity(LONG Units,STRPTR Destination,BOOL UseCurrency)
- {
- UBYTE IntegerBuffer[80]; // Sufficient, but too large
-
- STRPTR SignText, // Signed/unsigned quantity text
- SpaceText, // Currency/number separation
- Currency; // The name of the currency
- UBYTE SpaceSep, // A space separates currency and quantity?
- SignPos, // Where to place the sign text
- CSPos; // Where to place the currency text
- BYTE Sign; // Negative or positive quantity?
-
- // Negative quantity?
-
- if(Units < 0)
- {
- Sign = -1;
-
- Units = -Units;
- }
- else
- Sign = 1;
-
- // Does this currency sport a fractional smaller currency?
-
- if(Locale -> loc_MonFracDigits)
- {
- UBYTE NumberBuffer[5],
- FractionBuffer[40];
- LONG Integer,
- Fraction,
- Scale;
- WORD i;
-
- // Prepare the formatting string
-
- SPrintf(NumberBuffer,"%%0%ldld",Locale -> loc_MonFracDigits);
-
- // Turn the number of fractional digits into a power of ten
-
- for(i = 0, Scale = 1 ; i < Locale -> loc_MonFracDigits ; i++)
- Scale *= 10;
-
- // Split the quantity in integer and fractional part
-
- Integer = Units / Scale;
- Fraction = Units % Scale;
-
- // Build the integer text
-
- SPrintf(IntegerBuffer,"%ld",Integer);
-
- InsertGrouping(IntegerBuffer,Locale -> loc_MonGrouping,Locale -> loc_MonGroupSeparator);
-
- // Build the fractional text
-
- SPrintf(FractionBuffer,NumberBuffer,Fraction);
-
- InsertGrouping(FractionBuffer,Locale -> loc_MonFracGrouping,Locale -> loc_MonFracGroupSeparator);
-
- // Add the monetary decimal point
-
- strcat(IntegerBuffer,Locale -> loc_MonDecimalPoint);
-
- // Add the fractional part
-
- strcat(IntegerBuffer,FractionBuffer);
- }
- else
- {
- // Build the integer text
-
- SPrintf(IntegerBuffer,"%ld",Units);
-
- InsertGrouping(IntegerBuffer,Locale -> loc_MonGrouping,Locale -> loc_MonGroupSeparator);
- }
-
- // Pick up the appropriate formatting parameters
-
- if(Sign < 0)
- {
- SignText = Locale -> loc_MonNegativeSign;
- SpaceSep = Locale -> loc_MonNegativeSpaceSep;
- SignPos = Locale -> loc_MonNegativeSignPos;
- CSPos = Locale -> loc_MonNegativeCSPos;
- }
- else
- {
- SignText = Locale -> loc_MonPositiveSign;
- SpaceSep = Locale -> loc_MonPositiveSpaceSep;
- SignPos = Locale -> loc_MonPositiveSignPos;
- CSPos = Locale -> loc_MonPositiveCSPos;
- }
-
- // Are we to use the currency symbol?
-
- if(UseCurrency)
- {
- // Pick up the currency text
-
- Currency = Locale -> loc_MonCS;
-
- // Take care of the separation information
-
- if(SpaceSep == SS_NOSPACE)
- SpaceText = "";
- else
- SpaceText = " ";
- }
- else
- Currency = SpaceText = "";
-
- // Now merge all the information into one single string
-
- if(CSPos == CSP_PRECEDES)
- {
- switch(SignPos)
- {
- case SP_PARENS:
-
- // Currency (Space) Sign Value
- SPrintf(Destination,"(%s%s%s%s)",Currency,SpaceText,SignText,IntegerBuffer);
- break;
-
- case SP_PREC_ALL:
-
- // Sign Currency (Space) Value
- SPrintf(Destination,"%s%s%s%s",SignText,Currency,SpaceText,IntegerBuffer);
- break;
-
- case SP_SUCC_ALL:
-
- // Currency (Space) Value Sign
- SPrintf(Destination,"%s%s%s%s",Currency,SpaceText,IntegerBuffer,SignText);
- break;
-
- case SP_PREC_CURR:
-
- // Sign Currency (Space) Value
- SPrintf(Destination,"%s%s%s%s",SignText,Currency,SpaceText,IntegerBuffer);
- break;
-
- case SP_SUCC_CURR:
-
- // Currency Sign (Space) Value
- SPrintf(Destination,"%s%s%s%s",Currency,SignText,SpaceText,IntegerBuffer);
- break;
- }
- }
- else
- {
- switch(SignPos)
- {
- case SP_PARENS:
-
- // Sign Value (Space) Currency
- SPrintf(Destination,"(%s%s%s%s)",SignText,IntegerBuffer,SpaceText,Currency);
- break;
-
- case SP_PREC_ALL:
-
- // Sign Value (Space) Currency
- SPrintf(Destination,"%s%s%s%s",SignText,IntegerBuffer,SpaceText,Currency);
- break;
-
- case SP_SUCC_ALL:
-
- // Value (Space) Currency Sign
- SPrintf(Destination,"%s%s%s%s",IntegerBuffer,SpaceText,Currency,SignText);
- break;
-
- case SP_PREC_CURR:
-
- // Value (Space) Sign Currency
- SPrintf(Destination,"%s%s%s%s",IntegerBuffer,SpaceText,SignText,Currency);
- break;
-
- case SP_SUCC_CURR:
-
- // Value (Space) Currency Sign
- SPrintf(Destination,"%s%s%s%s",IntegerBuffer,SpaceText,Currency,SignText);
- break;
- }
- }
- }
-
- /* CreateSum(LONG Quantity):
- *
- * Create a string containing a monetary quantity formatted
- * according to the current locale rules.
- */
-
- STRPTR __regargs
- CreateSum(LONG Quantity,BYTE UseCurrency)
- {
- STATIC UBYTE Buffer[100];
-
- if(Locale)
- ConvertMonetaryQuantity(Quantity,Buffer,UseCurrency);
- else
- SPrintf(Buffer,"%ld.%02ld",Quantity / 100,Quantity % 100);
-
- return(Buffer);
- }
-
- /* LocalizeString(STRPTR *Strings,WORD From,WORD To):
- *
- * Localize an array of strings.
- */
-
- VOID __regargs
- LocalizeString(STRPTR *Strings,WORD From,WORD To)
- {
- WORD i,j;
-
- for(i = From, j = 0 ; i <= To ; i++)
- {
- if(!Strings[j])
- Strings[j++] = LocaleString(i);
- }
- }
-
- /* LocalizeStringTable(STRPTR *Strings,LONG *Table)
- *
- * Localize an array of strings.
- */
-
- VOID __regargs
- LocalizeStringTable(STRPTR *Strings,LONG *Table)
- {
- while(*Table != -1)
- *Strings++ = LocaleString(*Table++);
-
- *Strings = NULL;
- }
-
- /* LocalizeMenu(struct NewMenu *Menu,WORD From):
- *
- * Localize a NewMenu definition.
- */
-
- VOID __regargs
- LocalizeMenu(struct NewMenu *Menu,WORD From)
- {
- STRPTR Label,Shortcut;
-
- while(Menu -> nm_Type != NM_END)
- {
- Shortcut = LocaleString(From);
-
- if(Shortcut[0] && !Shortcut[1])
- Label = Shortcut + 2;
- else
- {
- Label = Shortcut;
- Shortcut = NULL;
- }
-
- switch(Menu -> nm_Type)
- {
- case NM_TITLE:
-
- Menu -> nm_Label = Label;
-
- From++;
-
- break;
-
- case NM_ITEM:
- case NM_SUB:
-
- if(Menu -> nm_Label != NM_BARLABEL)
- {
- Menu -> nm_Label = Label;
- Menu -> nm_CommKey = Shortcut;
-
- From++;
- }
-
- break;
- }
-
- Menu++;
- }
- }
-
- VOID __regargs
- LocalizeMenuTable(struct NewMenu *Menu,LONG *Table)
- {
- STRPTR Label,Shortcut;
- LONG From = 0;
-
- while(Menu -> nm_Type != NM_END)
- {
- Shortcut = LocaleString(Table[From]);
-
- if(Shortcut[0] && !Shortcut[1])
- Label = Shortcut + 2;
- else
- {
- Label = Shortcut;
- Shortcut = NULL;
- }
-
- switch(Menu -> nm_Type)
- {
- case NM_TITLE:
-
- Menu -> nm_Label = Label;
-
- From++;
-
- break;
-
- case NM_ITEM:
- case NM_SUB:
-
- if(Menu -> nm_Label != NM_BARLABEL)
- {
- Menu -> nm_Label = Label;
- Menu -> nm_CommKey = Shortcut;
-
- From++;
- }
-
- break;
- }
-
- Menu++;
- }
- }
-
- /* LocaleString(LONG ID):
- *
- * Obtain a string from the translation pool.
- */
-
- STRPTR __regargs
- LocaleString(LONG ID)
- {
- STRPTR Builtin;
-
- if(ID < NumAppStrings && AppStrings[ID] . cca_ID == ID)
- Builtin = AppStrings[ID] . cca_Str;
- else
- {
- LONG i;
-
- Builtin = "";
-
- for(i = 0 ; i < NumAppStrings ; i++)
- {
- if(AppStrings[i] . cca_ID == ID)
- {
- Builtin = AppStrings[i] . cca_Str;
-
- break;
- }
- }
- }
-
- if(Catalog)
- {
- STRPTR String = GetCatalogStr(Catalog,ID,Builtin);
-
- if(String[0])
- return(String);
- else
- return(Builtin);
- }
- else
- return(Builtin);
- }
-
- STRPTR __saveds __asm
- LocaleHookFunc(register __a0 struct Hook *Hook,register __a1 LONG ID)
- {
- return(LocaleString(ID));
- }
-
- STATIC LONG __saveds __asm
- FormatDateHookFunc(register __a0 struct Hook *Hook,register __a1 UBYTE Char)
- {
- STRPTR String = Hook -> h_Data;
-
- *String++ = Char;
-
- Hook -> h_Data = String;
-
- return(TRUE);
- }
-
- /* FormatStamp():
- *
- * Convert a date stamp into human readable
- * form by taking the current locale parameters
- * into account.
- */
-
- BOOLEAN __regargs
- FormatStamp(struct DateStamp *Stamp,STRPTR DateBuffer,STRPTR TimeBuffer,STRPTR BothBuffer,BOOLEAN SubstituteDay)
- {
- struct DateStamp Now;
-
- // If no time stamp given, do with current time
-
- if(!Stamp)
- DateStamp(Stamp = &Now);
-
- // Is the current locale available?
-
- if(Locale)
- {
- struct Hook LocalHook = {{NULL}, (HOOKFUNC)FormatDateHookFunc};
-
- // Combine date and time text?
-
- if(BothBuffer && !SubstituteDay)
- {
- LocalHook . h_Data = BothBuffer;
-
- FormatDate(Locale,Locale -> loc_DateTimeFormat,Stamp,&LocalHook);
-
- StripSpaces(BothBuffer);
- }
- else
- {
- UBYTE LocalDateBuffer[40],
- LocalTimeBuffer[40];
-
- // Provide storage space
-
- if(BothBuffer)
- {
- DateBuffer = LocalDateBuffer;
- TimeBuffer = LocalTimeBuffer;
- }
-
- // Do we have a date buffer to fill?
-
- if(DateBuffer)
- {
- // Are we to substitute the current day with
- // text such as today, yesterday, etc.?
-
- if(SubstituteDay)
- {
- struct DateStamp Today;
- STRPTR String;
-
- // Get the current time
-
- DateStamp(&Today);
-
- // Does the date refer to yesterday?
-
- if(Stamp -> ds_Days == Today . ds_Days - 1)
- String = GetLocaleStr(Locale,YESTERDAYSTR);
- else
- {
- // Does the date refer to today?
-
- if(Stamp -> ds_Days == Today . ds_Days)
- String = GetLocaleStr(Locale,TODAYSTR);
- else
- {
- // Does the date refer to tomorrow?
-
- if(Stamp -> ds_Days == Today . ds_Days + 1)
- String = GetLocaleStr(Locale,TOMORROWSTR);
- else
- {
- String = NULL;
- SubstituteDay = NULL;
- }
- }
- }
-
- if(String)
- strcpy(DateBuffer,String);
- else
- DateBuffer[0] = 0;
- }
-
- if(!SubstituteDay)
- {
- LocalHook . h_Data = DateBuffer;
-
- FormatDate(Locale,Locale -> loc_DateFormat,Stamp,&LocalHook);
- }
-
- StripSpaces(DateBuffer);
- }
-
- if(TimeBuffer)
- {
- LocalHook . h_Data = TimeBuffer;
-
- FormatDate(Locale,Locale -> loc_TimeFormat,Stamp,&LocalHook);
-
- StripSpaces(TimeBuffer);
- }
-
- // Combine date and time
-
- if(BothBuffer)
- {
- strcpy(BothBuffer,DateBuffer);
- strcat(BothBuffer," ");
- strcat(BothBuffer,TimeBuffer);
- }
- }
- }
- else
- {
- struct DateTime DateTime;
- UBYTE LocalDateBuffer[40],
- LocalTimeBuffer[40];
-
- // Provide storage space
-
- if(BothBuffer)
- {
- DateBuffer = LocalDateBuffer;
- TimeBuffer = LocalTimeBuffer;
- }
-
- // No locale, so we will use dos.library instead.
-
- CopyMem(Stamp,&DateTime . dat_Stamp,sizeof(struct DateStamp));
-
- DateTime . dat_Format = FORMAT_DOS;
- DateTime . dat_Flags = SubstituteDay ? DTF_SUBST : NULL;
- DateTime . dat_StrDay = NULL;
- DateTime . dat_StrDate = DateBuffer;
- DateTime . dat_StrTime = TimeBuffer;
-
- if(!DateToStr(&DateTime))
- return(FALSE);
-
- if(DateBuffer)
- StripSpaces(DateBuffer);
-
- if(TimeBuffer)
- StripSpaces(TimeBuffer);
-
- // Combine date and time
-
- if(BothBuffer)
- {
- strcpy(BothBuffer,DateBuffer);
- strcat(BothBuffer," ");
- strcat(BothBuffer,TimeBuffer);
- }
- }
-
- return(TRUE);
- }
-
- /* FormatTime(STRPTR Buffer,LONG Hours,LONG Minutes,LONG Seconds):
- *
- * Given hours, minutes and seconds, format this data into
- * a human-readable string.
- */
-
- VOID __regargs
- FormatTime(STRPTR Buffer,LONG Hours,LONG Minutes,LONG Seconds)
- {
- if(Locale)
- {
- struct Hook LocalHook = {{NULL}, (HOOKFUNC)FormatDateHookFunc};
-
- struct DateStamp Stamp;
-
- Stamp . ds_Days = 0;
- Stamp . ds_Minute = Hours * 60 + Minutes;
- Stamp . ds_Tick = MAX(0,Seconds) * TICKS_PER_SECOND;
-
- LocalHook . h_Data = Buffer;
-
- if(Seconds < 0)
- FormatDate(Locale,Locale -> loc_ShortTimeFormat,&Stamp,&LocalHook);
- else
- FormatDate(Locale,Locale -> loc_TimeFormat,&Stamp,&LocalHook);
- }
- else
- {
- if(Seconds < 0)
- SPrintf(Buffer,"%02ld:%02ld",Hours,Minutes);
- else
- SPrintf(Buffer,"%02ld:%02ld:%02ld",Hours,Minutes,Seconds);
- }
- }
-